#include "socket.h"
#include "socket_p.h"
#include <QtNetwork>

class QtData : public SocketData
{
public:
    QtData() : socket(0), server(0) {}
    ~QtData() { delete socket; delete server; }

    QTcpSocket *socket;
    QTcpServer *server;
};

#define qt_socketData() (static_cast<QtData*>(data))

Socket::Socket()
{
    data = new QtData;
}

Socket::~Socket()
{
    delete data;
}

bool Socket::connectToServer(const std::string &host, int port)
{
    QTcpSocket *&socket = qt_socketData()->socket;
    if (!socket)
        socket = new QTcpSocket;
    socket->connectToHost(QString::fromStdString(host), port);
    if (!socket->waitForConnected()) {
        return false;
    }
    data->server = host;
    data->port = port;
    return true;
}

int Socket::bytesAvailable() const
{
    if (!qt_socketData()->socket || qt_socketData()->socket->state() != QTcpSocket::ConnectedState)
        return -1;
    return qt_socketData()->socket->bytesAvailable();
}

bool Socket::waitForBytesAvailable(int bytes, int timeout)
{
    QTcpSocket *socket = qt_socketData()->socket;
    if (!socket || socket->state() != QTcpSocket::ConnectedState)
        return false;
    QTime timer;
    if (timeout > 0)
        timer.start();

    while (socket->bytesAvailable() < bytes && (timeout == 0 || timer.elapsed() < timeout)) {
        socket->waitForReadyRead(timeout > 0 ? timeout - timer.elapsed() : 0);
        // ### is this right?
    }

    return socket->bytesAvailable() >= bytes;
}

int Socket::write(const char *dat, int size)
{
    QTcpSocket *socket = qt_socketData()->socket;
    return socket ? socket->write(dat, size) : -1;
}

int Socket::read(char *buffer, int max)
{
    QTcpSocket *socket = qt_socketData()->socket;
    return socket ? socket->read(buffer, max) : -1;
}

#undef qt_socketData
